from django.shortcuts import render
from django.views import View
# Create your views here.
from users.models import User
from django.http import JsonResponse
import json
from django.contrib.auth import logout
from django.contrib.auth import login
from django_redis import get_redis_connection
import re,logging
logger = logging.getLogger('django')


class UsernameCountView(View):
    # 请求方式GET，所以重写self.get视图函数
    # 路径中传递用户名参数，所以视图函数self.get就必须定义一个形式参数接收路径传参
    def get(self, request, username):
        # 1.提取参数
        # 2.效验参数
        # 3.业务数据处理 —— 数据库的查询统计
        count = User.objects.filter(username=username).count()
        # 4.构建响应（响应参数）
        return JsonResponse({
            'code': 0,
            'errnsg': 'ok',
            'count': count,
        })


class MobileCountView(View):
    def get(self, request, mobile):
        try:
            count = User.objects.filter(mobile=mobile).count()
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '查询数据库出错'})

            # 2.返回结果(json)
        return JsonResponse({'code': 0,
                             'errmsg': 'ok',
                             'count': count
                             })


class RegisterView(View):
    def post(self, request):
        # 1.提取参数
        data = json.loads(request.body.decode())

        username = data.get('username')
        password = data.get('password')
        password2 = data.get('password2')
        mobile = data.get('mobile')
        allow = data.get('allow',False)
        sms_code = data.get('sms_code')
        # 2.校验参数
        # 判断是否同意协议
        if not allow:
            return JsonResponse({'code':400,'errmsg':'请勾选同意协议'})

        # 2.3 业务性校验
        if not all([username,password,password2,mobile,sms_code]):
            return JsonResponse({'code':400,'errmsg':'缺少必要参数'})

        if not re.match(r'^[a-zA-Z0-9]{5,20}$',username):
            return JsonResponse({'code':400,'errmsg':'输入格式有误'})

        if not re.match(r'^[a-zA-Z0-9]{8,20}$',password):
            return JsonResponse({'code':400,'errmsg':'密码格式有误'})

        if not re.match(r'^[a-zA-Z0-9]{8,20}$',password2):
            return JsonResponse({'code':400,'errmsg':'密码格式有误'})

        if not re.match(r'1[3-9]\d{9}',mobile):
            return JsonResponse({'code':400,'errmsg':'手机号输入错误'})
        #TODO: 补充状态保持逻辑代码

        conn = get_redis_connection('verify_code')# 2号库
        redis_sms_code = conn.get('sms_%s' %mobile)
        if not redis_sms_code:
            return JsonResponse({'code':400,'errmsg':'短信验证码过期'})
        if redis_sms_code.decode() != sms_code:
            return JsonResponse({'code':400,'errmsg':'短信验证码有误'})
        # 3 业务数据处理
        try:
            User.objects.create_user(
                username=username,
                password=password,
                mobile=mobile
            )
        except Exception as e:
            return JsonResponse({'code':400,'errmsg':'注册失败'})
        login(request,username)
        # 3.1 新建用户数据
        # user = User.objects.create() --> create函数无法加密用户密码
        response = JsonResponse({'code':0,'errmsg':'注册成功'})
        # 在响应对象中设置用户名信息.
        # 将用户名写入到 cookie，有效期 14 天
        response.set_cookie('username', user.username, max_age=3600 * 24 * 14)
        # 返回响应结果
        return response


# 用户传统登入
class LoginView(View):
    
    def post(self,request):
        # 1.提取参数
        data = json.loads(request.body.decode())
        
        username = data.get('username')
        password = data.get('password')
        remebered = data.get('rembered',False)
        
        # 2.校验参数
        if not all([username,password]):
            return JsonResponse({'code':400,'errmsg':'缺少必要参数'})

        if not re.match(r'^[a-zA-Z0-9]{5,20}$',username):
            return JsonResponse({'code':400,'errmsg':'用户名格式有误'})
        if not re.match(r'^[a-zA-Z0-9]{8,20}$',password):
            return JsonResponse({'code':400,'errmsg':'密码格式有误'})
        # 3.业务数据处理
        # TODO: 方案一 =======手动校验用户名和密码=======
        # 根据用户和密码验证用户身份逻辑
        # (1). 根据用户名过滤单一用户对象
        # try:
        #     user = User.objects.get(username=username)
        # except User.DoseNotExist as e:
        #     # 如果输出DoesNotExist异常，表明没有过滤出用户(表明用户名不存在)
        #     return JsonResponse({
        #         'code':400,
        #         'errmsg':'用户名或密码错误'
        #     })
        # # (2). 校验明文密码
        # # 明文密码 12345678  ------> 数据库中的密文密码
        # # check_password(password):功能校验明文密码；参数是明文密码；返回值True表示正确,False表示错误
        # if not user.check_password(password):
        #     return JsonResponse({
        #         'code':400,
        #         'errmsg':'用户名或密码错误'
        #     })


        # TODO:多账号登入方案一 =======修改User.USERNAME_FIELD属性制定唯一过滤字段=======
        # 注意：前端传来的username有可能是用户名,也有可能是手机号
        # if re.match(r'^1[3-9]\d{9}$',username):
        #     # 如果前端传来是手机号,需要使用mobile字段作唯一过滤
        #     User.USERNAME_FIELD = 'mobile'
        # else:
        #     # 否则使用username作为字段唯一过滤
        #     User.USERNAME_FIELD = 'username'
        #
        # TODO: 方案二 ========使用全局authenticate认证函数来校验用户名和密码实现传统认证
        from django.contrib.auth import authenticate
        # authenticate(request,username='xxx',password='xxx')
        # 全局认证函数: 功能是校验用户身份
        # 参数: request请求对象,username用户名,password明文密码
        # 返回值: 用户模型类对象 或 None
        user = authenticate(request,username=username,password=password)
        if user is None:
            # authenticate函数返回None表明用户身份认证失败
            return JsonResponse({
                'code':400,
                'errmsg':'用户名或密码错误'
            })
        # 状态保持
        login(request,user)

        if remebered != True:
            # 设置session数据再浏览器标签页关闭失效
            request.session.set_expiry(0)
        else:
            request.session.set_expiry(None)
        # 4.构建响应
        # 生成响应对象
        response = JsonResponse({'code': 0, 'errmsg': 'ok'})
        # 在响应对象中设置用户名信息.
        # 将用户名写入到 cookie，有效期 14 天
        response.set_cookie('username', user.username, max_age=3600 * 24 * 14)
        # 返回响应结果
        return response

class LogoutView(View):
    """定义退出登录的接口"""

    def delete(self, request):
        # 清理 session
        logout(request)
        # 创建 response 对象.
        response = JsonResponse({'code':0, 'errmsg':'ok'})
        # 调用对象的 delete_cookie 方法, 清除cookie
        response.delete_cookie('username')
        # 返回响应
        return response


# 获取用户中心页的用户信息
class UserInfoView(View):

    def get(self,request):
        # 1.提取参数 —— Cookie参数
        # 2.校验参数
        # 3.业务数据处理 ——获取登陆的用户对象,构造响应参数
        # TODO: 如何再视图函数中,获取当前请求登陆了的用户对象
        # 结论：django通过cookie中的session id,获取到了状态保持的用户信息(用户id)
        # 然后再进一步获取用户模型类对象,并且把该对象封装成了request.user属性
        # 总结一句话记忆:request.user属性,(1).就是当前登录的用户对象;(2).如果未登录则是一个AnonymousUser匿名用户对象
        user = request.user


        # TODO:限制当前接口必须登录才能访问
        if not user.is_authenticated:
            # 说明user是一个AnonymousUser对象 —— 未登录
            return JsonResponse({
                'code':400,
                'errmsg':'用户未登入'
            })
        # 4.构建响应
        return JsonResponse({
            'code':0,
            'errmsg':'OK',
            'info_data':{
                'username':user.username,
                'mobile':user.mobile,
                'email':user.email,
                'email_active':False # 后续需要追加验证邮箱的字段
            }

        })



